﻿//-------------------------------------------------------------------------------
// <copyright file="FBApplication.cs" company="TaskyMedia LLC">
//     Copyright (c) TaskyMedia LLC.
// </copyright>
//-------------------------------------------------------------------------------

/*
 * Copyright (c) 2010, TaskyMedia LLC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *   Redistributions of source code must retain the above copyright notice, this 
 *     list of conditions and the following disclaimer.
 *   Redistributions in binary form must reproduce the above copyright notice, this
 *     list of conditions and the following disclaimer in the documentation and/or
 *     other materials provided with the distribution.
 *   Neither the name of TaskyMedia LLC nor the names of its contributors may be used
 *   to endorse or promote products derived from this software without specific prior
 *   written permission.
 *   
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE. 
 */

namespace FBGraphApi
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// Provides a functionality for an application using the Facebook Graph API implementation.
    /// </summary>
    public class FBApplication
    {
        /// <summary>
        /// Facebook Application Id.
        /// </summary>
        private string _applicationId;

        /// <summary>
        /// Facebook Application Secret.
        /// </summary>
        private string _applicationSecret;

        /// <summary>
        /// List of <see cref="ExtendedPermission">extended permissions</see> requested
        /// by the Application.
        /// </summary>
        private List<ExtendedPermission> _requestedPermissions;

        /// <summary>
        /// Authorized Facebook Graph API session.
        /// </summary>
        private FBSession _session;

        /// <summary>
        /// Current application user.
        /// </summary>
        private User _currentUser;

        /// <summary>
        /// Initializes a new instance of the <see cref="FBApplication"/> class.
        /// </summary>
        public FBApplication()
        {
            this._applicationId = FBSettings.ClientId;
            this._applicationSecret = FBSettings.ClientSecret;
            if (FBSettings.RequestedPermissions == null)
            {
                this._requestedPermissions = new List<ExtendedPermission>();
            }
            else
            {
                this._requestedPermissions = new List<ExtendedPermission>(FBSettings.RequestedPermissions);
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FBApplication"/> class.
        /// </summary>
        /// <param name="accessToken">A Facebook Graph API access token.</param>
        public FBApplication(string accessToken)
            : this()
        {
            this._session = new FBSession(accessToken);
            this._currentUser = new User(this);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FBApplication"/> class.
        /// </summary>
        /// <param name="session">An authorized <see cref="FBSession">Facebook Graph API session</see>.</param>
        public FBApplication(FBSession session)
            : this()
        {
            this._session = session;
            this._currentUser = new User(this);
        }

        /// <summary>
        /// Gets the current user.
        /// </summary>
        /// <value>The current user.</value>
        public User CurrentUser
        {
            get
            {
                return this._currentUser;
            }
        }

        /// <summary>
        /// Gets a user based on the specified identifier.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>Returns a <see cref="User" /> object.</returns>
        public User GetUser(string id)
        {
            return new User(this, id);
        }

        /// <summary>
        /// Ensures that the specified <see cref="ExtendedPermission" /> has been granted
        /// to the application, according to the application configuration.
        /// </summary>
        /// <param name="permission">The <see cref="ExtendedPermission" /> to demand.</param>
        /// <returns>Returns <c>true</c> if the permission has been granted; otherwise,
        /// <c>false</c>.</returns>
        internal bool DemandPermission(ExtendedPermission permission)
        {
            return this._requestedPermissions.Contains(permission);
        }

        /// <summary>
        /// Gets the list of extended permissions granted to the Application.
        /// </summary>
        /// <returns>List of extended permissions.</returns>
        internal ExtendedPermission[] GetExtendedPermissions()
        {
            return this._requestedPermissions.ToArray();
        }

        /// <summary>
        /// Gets the result from a request against the Facebook Graph.
        /// </summary>
        /// <param name="objectPath">The object path. For example, if requesting
        /// profile for the current user, the object path would be "me".</param>
        /// <param name="additionalParams">Any additional <see cref="WebRequestParameter">parameters</see>
        /// for the request.</param>
        /// <returns>Returns the JSON string with the result.</returns>
        internal string GetRequest(string objectPath, params WebRequestParameter[] additionalParams)
        {
            WebRequestParameter[] paramsList = new WebRequestParameter[additionalParams.Length + 1];
            paramsList[0] = new WebRequestParameter("access_token", this._session.AccessToken);

            if (additionalParams.Length > 0)
            {
                Array.Copy(additionalParams, 0, paramsList, 1, additionalParams.Length);
            }

            string uri = String.Format("https://graph.facebook.com/{0}", objectPath);

            return WebRequestHelper.Get(uri, paramsList).Data;
        }
    }
}
